package com.bobbygu.bobbyapp.function.dragphoto

import android.animation.Animator
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.widget.ImageView
import com.bobbygu.lib.mvvm.common.BaseActivity
import com.bobbygu.lib.mvvm.common.BaseModel
import com.bobbygu.lib.mvvm.common.BaseViewModel
import com.bobbygu.bobbyapp.R
import com.wingsofts.dragphotoview.DragPhotoView
import android.view.WindowManager
import android.view.ViewTreeObserver
import android.view.ViewGroup
import android.support.v4.view.PagerAdapter
import android.os.Build
import android.view.View
import kotlinx.android.synthetic.main.activity_drag_photo.*


/**
 *
 * # time: 2017/11/27 18:05
 * # e-mail: gubojun@csii.com.cn
 * @author 顾博君
 * @since 1.0
 */
@Suppress("FINITE_BOUNDS_VIOLATION_IN_JAVA")
class DragPhotoActivity<VM : BaseViewModel<*, *>, M : BaseModel<*>> : BaseActivity<VM, M>() {
    private var mList: ArrayList<String> = ArrayList()
    private var mPhotoViews: Array<DragPhotoView>? = null

    var mOriginLeft = 0
    var mOriginTop = 0
    var mOriginHeight = 0
    var mOriginWidth = 0
    var mOriginCenterX = 0
    var mOriginCenterY = 0
    private var mTargetHeight = 0f
    private var mTargetWidth = 0f
    private var mScaleX = 0f
    private var mScaleY = 0f
    private var mTranslationX = 0f
    private var mTranslationY = 0f
    override fun getLayoutId(): Int = R.layout.activity_drag_photo
    override fun initView() {
        window.setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            window.statusBarColor = resources.getColor(R.color.colorPrimary)
        }

        mList.add("path")
        mList.add("path")
        mList.add("path")

        mPhotoViews = Array(mList.size, {
            (View.inflate(this, R.layout.item_viewpager, null) as DragPhotoView).apply {
                setImageResource(R.drawable.ic_launcher_round)
                setOnTapListener { finishWithAnimation() }
                setOnExitListener { view, x, y, w, h -> performExitAnimation(view, x, y, w, h) }
            }
        })

        viewpager.adapter = object : PagerAdapter() {
            override fun getCount(): Int = mList.size

            override fun instantiateItem(container: ViewGroup, position: Int): Any {
                container.addView(mPhotoViews!![position])
                return mPhotoViews!![position]
            }

            override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
                container.removeView(mPhotoViews!![position])
            }

            override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object`
        }

        if (viewpager != null)
            viewpager.viewTreeObserver
                    .addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
                        @SuppressLint("NewApi")
                        override fun onGlobalLayout() {
                            viewpager.viewTreeObserver.removeOnGlobalLayoutListener(this)

                            mOriginLeft = intent.getIntExtra("left", 0)
                            mOriginTop = intent.getIntExtra("top", 0)
                            mOriginHeight = intent.getIntExtra("height", 0)
                            mOriginWidth = intent.getIntExtra("width", 0)
                            mOriginCenterX = mOriginLeft + mOriginWidth / 2
                            mOriginCenterY = mOriginTop + mOriginHeight / 2

                            val location = IntArray(2)

                            val photoView = mPhotoViews!![0]
                            photoView.getLocationOnScreen(location)

                            mTargetHeight = photoView.height.toFloat()
                            mTargetWidth = photoView.width.toFloat()
                            mScaleX = mOriginWidth.toFloat() / mTargetWidth
                            mScaleY = mOriginHeight.toFloat() / mTargetHeight

                            val targetCenterX = location[0] + mTargetWidth / 2
                            val targetCenterY = location[1] + mTargetHeight / 2

                            mTranslationX = mOriginCenterX - targetCenterX
                            mTranslationY = mOriginCenterY - targetCenterY
                            photoView.translationX = mTranslationX
                            photoView.translationY = mTranslationY

                            photoView.scaleX = mScaleX
                            photoView.scaleY = mScaleY

                            performEnterAnimation()

                            for (i in 0 until mPhotoViews!!.size) {
                                mPhotoViews!![i].minScale = mScaleX
                            }
                        }
                    })
    }

    /**
     * ===================================================================================
     *
     *
     * 底下是低版本"共享元素"实现   不需要过分关心  如有需要 可作为参考.
     *
     *
     * Code  under is shared transitions in all android versions implementation
     */
    private fun performExitAnimation(view: DragPhotoView, x: Float, y: Float, w: Float, h: Float) {
        view.finishAnimationCallBack()
        val viewX = mTargetWidth / 2 + x - mTargetWidth * mScaleX / 2
        val viewY = mTargetHeight / 2 + y - mTargetHeight * mScaleY / 2
        view.x = viewX
        view.y = viewY

        val centerX = view.x + mOriginWidth / 2
        val centerY = view.y + mOriginHeight / 2

        val translateX = mOriginCenterX - centerX
        val translateY = mOriginCenterY - centerY


        val translateXAnimator = ValueAnimator.ofFloat(view.x, view.x + translateX)
        translateXAnimator.addUpdateListener { valueAnimator -> view.x = valueAnimator.animatedValue as Float }
        translateXAnimator.duration = 300
        translateXAnimator.start()
        val translateYAnimator = ValueAnimator.ofFloat(view.y, view.y + translateY)
        translateYAnimator.addUpdateListener { valueAnimator -> view.y = valueAnimator.animatedValue as Float }
        translateYAnimator.addListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animator: Animator) {}
            override fun onAnimationCancel(animator: Animator) {}
            override fun onAnimationRepeat(animator: Animator) {}
            override fun onAnimationEnd(animator: Animator) {
                animator.removeAllListeners()
                finish()
                overridePendingTransition(0, 0)
            }
        })
        translateYAnimator.duration = 300
        translateYAnimator.start()
    }

    private fun finishWithAnimation() {
        val photoView = mPhotoViews!![0]
        val translateXAnimator = ValueAnimator.ofFloat(0f, mTranslationX)
        translateXAnimator.addUpdateListener { valueAnimator -> photoView.x = valueAnimator.animatedValue as Float }
        translateXAnimator.duration = 300
        translateXAnimator.start()

        val translateYAnimator = ValueAnimator.ofFloat(0f, mTranslationY)
        translateYAnimator.addUpdateListener { valueAnimator -> photoView.y = valueAnimator.animatedValue as Float }
        translateYAnimator.duration = 300
        translateYAnimator.start()

        val scaleYAnimator = ValueAnimator.ofFloat(1f, mScaleY)
        scaleYAnimator.addUpdateListener { valueAnimator -> photoView.scaleY = valueAnimator.animatedValue as Float }
        scaleYAnimator.duration = 300
        scaleYAnimator.start()

        val scaleXAnimator = ValueAnimator.ofFloat(1f, mScaleX)
        scaleXAnimator.addUpdateListener { valueAnimator -> photoView.scaleX = valueAnimator.animatedValue as Float }

        scaleXAnimator.addListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animator: Animator) {}
            override fun onAnimationCancel(animator: Animator) {}
            override fun onAnimationRepeat(animator: Animator) {}
            override fun onAnimationEnd(animator: Animator) {
                animator.removeAllListeners()
                finish()
                overridePendingTransition(0, 0)
            }
        })
        scaleXAnimator.duration = 300
        scaleXAnimator.start()
    }

    private fun performEnterAnimation() {
        val photoView = mPhotoViews!![0]
        val translateXAnimator = ValueAnimator.ofFloat(photoView.x, 0f)
        translateXAnimator.addUpdateListener { valueAnimator -> photoView.x = valueAnimator.animatedValue as Float }
        translateXAnimator.duration = 300
        translateXAnimator.start()

        val translateYAnimator = ValueAnimator.ofFloat(photoView.y, 0f)
        translateYAnimator.addUpdateListener { valueAnimator -> photoView.y = valueAnimator.animatedValue as Float }
        translateYAnimator.duration = 300
        translateYAnimator.start()

        val scaleYAnimator = ValueAnimator.ofFloat(mScaleY, 1f)
        scaleYAnimator.addUpdateListener { valueAnimator -> photoView.scaleY = valueAnimator.animatedValue as Float }
        scaleYAnimator.duration = 300
        scaleYAnimator.start()

        val scaleXAnimator = ValueAnimator.ofFloat(mScaleX, 1f)
        scaleXAnimator.addUpdateListener { valueAnimator -> photoView.scaleX = valueAnimator.animatedValue as Float }
        scaleXAnimator.duration = 300
        scaleXAnimator.start()
    }

    override fun onBackPressed() {
        finishWithAnimation()
    }

    companion object {

        /**
         * @param activity Activity
         */
        fun startActivity(activity: Activity, imageView: ImageView) {
            val intent = Intent(activity, DragPhotoActivity::class.java)
            val location = IntArray(2)
            imageView.getLocationOnScreen(location)
            intent.putExtra("left", location[0])
            intent.putExtra("top", location[1])
            intent.putExtra("height", imageView.height)
            intent.putExtra("width", imageView.width)
            activity.startActivity(intent)
            activity.overridePendingTransition(0, 0)
        }
    }
}